return __dev_alloc_skb(length, GFP_ATOMIC);
}
+#include <asm/domain_page.h>
+
static inline void *kmap_skb_frag(const skb_frag_t *frag)
{
- return page_address(frag->page);
+ return map_domain_mem(__pa(page_address(frag->page)));
}
static inline void kunmap_skb_frag(void *vaddr)
{
+ unmap_domain_mem(vaddr);
}
extern int skb_copy_bits(const struct sk_buff *skb,
int offset, void *to, int len);
extern void skb_init(void);
-extern int skb_linearize(struct sk_buff *skn, int gfp_mask);
-
#endif /* _LINUX_SKBUFF_H */
{
struct net_device *dev = the_dev;
struct list_head *ent;
- struct sk_buff *skb;
+ struct sk_buff *skb, *nskb;
net_vif_t *vif;
tx_shadow_entry_t *tx;
/* Is the NIC crap? */
if ( !(dev->features & NETIF_F_SG) )
- skb_linearize(skb, GFP_KERNEL);
+ {
+ nskb = skb_copy(skb, GFP_KERNEL);
+ kfree_skb(skb);
+ skb = nskb;
+ }
/* Transmit should always work, or the queue would be stopped. */
if ( dev->hard_start_xmit(skb, dev) != 0 )
return n;
}
-/* Keep head the same: replace data */
-int skb_linearize(struct sk_buff *skb, int gfp_mask)
-{
- unsigned int size;
- u8 *data;
- long offset;
- int headerlen = skb->data - skb->head;
- int expand = (skb->tail+skb->data_len) - skb->end;
-
- if (skb_shinfo(skb)->nr_frags == 0)
- return 0;
-
- if (expand <= 0)
- expand = 0;
-
- size = (skb->end - skb->head + expand);
- size = SKB_DATA_ALIGN(size);
- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
- if (data == NULL)
- return -ENOMEM;
-
- /* Copy entire thing */
- if (skb_copy_bits(skb, -headerlen, data, headerlen+skb->len))
- BUG();
-
- /* Offset between the two in bytes */
- offset = data - skb->head;
-
- /* Free old data. */
- skb_release_data(skb);
-
- skb->head = data;
- skb->end = data + size;
-
- /* Set up new pointers */
- skb->h.raw += offset;
- skb->nh.raw += offset;
- skb->mac.raw += offset;
- skb->tail += offset;
- skb->data += offset;
-
- skb->skb_type = SKB_NORMAL;
-
- /* Set up shinfo */
- skb_shinfo(skb)->nr_frags = 0;
-
- skb->tail += skb->data_len;
- skb->data_len = 0;
- return 0;
-}
-
/* Copy some data bits from skb to kernel buffer. */
int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)